use aruspider::component::request::{Method, Request, RequestBody};
use aruspider::component::response::Response;
use aruspider::component::{ParseResult, Task};
use aruspider::spider::Spider;
use std::collections::HashMap;
// use async_trait::async_trait;
use log::{debug, error};
use std::sync::Arc;
use url::Url;

#[derive(Debug)]
pub struct HttpbinSpider {
    pub start_urls: Vec<&'static str>,
}

// #[async_trait]
impl Spider for HttpbinSpider {
    type M = i32;
    type ItemType = String;
    fn start_urls(&self) -> &[&'static str] {
        self.start_urls.as_slice()
    }

    fn start_tasks(&self) -> Vec<Task<Self::M, Self::ItemType>> {
        let mut tasks = vec![];

        match Url::parse("http://httpbin.org/cookies/set") {
            Ok(url) => {
                debug!("为 [{}] 创建请求", url);
                let mut query = HashMap::new();
                query.insert("freedom".to_string(), "2345".to_string());
                let req = Request::new(url, Method::GET, None, Some(query), RequestBody::Empty);
                let task = Task {
                    req,
                    meta: Some(1111),
                    parser: Some(Arc::new(bin_parse_first)),
                };
                tasks.push(task);
            }
            Err(e) => error!("创建请求失败, {}", e),
        }
        tasks
    }
}

async fn bin_parse_first(resp: Response, metadata: Option<i32>) -> ParseResult<i32, String> {
    let mut tasks = vec![];
    let mut items = vec![];

    items.push(resp.resp.text().await.unwrap());
    println!("-----> {:?}", metadata);
    for i in 1..11 {
        match Url::parse(&format!("http://httpbin.org/delay/1?id={}", i)) {
            Ok(url) => {
                debug!("为 [{}] 创建请求", url);
                let req = Request::new(url, Method::GET, None, None, RequestBody::Empty);
                let task = Task {
                    req,
                    meta: Some(1111),
                    parser: Some(Arc::new(bin_parse_second)),
                };
                tasks.push(task);
            }
            Err(e) => error!("创建请求失败, {}", e),
        }
    }

    // 再添加几个 post
    for i in 0..10 {
        match Url::parse("http://httpbin.org/post") {
            Ok(url) => {
                let mut query = HashMap::new();
                query.insert(String::from("id"), i.to_string());
                let mut data = HashMap::new();
                data.insert("username".to_string(), "codergege".to_string());
                data.insert("password".to_string(), "123".to_string());
                let body = RequestBody::Form(data);
                let req = Request::new(url, Method::POST, None, Some(query), body);
                let task = Task {
                    req,
                    meta: Some(i),
                    parser: Some(Arc::new(bin_parse_second)),
                };
                tasks.push(task);
            }
            Err(e) => error!("创建 post 请求失败 {}", e),
        }
    }

    ParseResult::new(tasks, items)
}

async fn bin_parse_second(resp: Response, metadata: Option<i32>) -> ParseResult<i32, String> {
    let tasks = vec![];
    let mut items = vec![];

    items.push(resp.resp.text().await.unwrap());
    println!("-----> {:?}", metadata);

    ParseResult::new(tasks, items)
}
